package model.workersWithData;

import java.util.ArrayList;
import java.util.Date;

import model.workersWithData.sort.SortBy;
import model.workersWithData.sort.SortObjectBy;
import model.workerwithfile.ReaderFromFile;
import model.workerwithfile.WriterInFile;
import api.entitites.IDataBase;
import api.entitites.IGarage;
import api.entitites.IMaster;
import api.entitites.IOrder;
import api.entitites.OrderStatus;
import api.exportimportentities.IExportImportEntities;
import api.messages.Messager;
import api.model.IDBManager;
import autoproperties.AutoProperties;
import entitiesfactory.EntitiesFactory;

public class DBManager implements IDBManager {

	private ArrayList<IOrder> orderList = new ArrayList<IOrder>();
	private ArrayList<IMaster> masterList = new ArrayList<IMaster>();
	private ArrayList<IGarage> garageList = new ArrayList<IGarage>();
	private IDataBase db;
	private IExportImportEntities export_import_entities;
	private AutoProperties auto_properties = AutoProperties.getInstance();

	

	private EntitiesFactory entities_factory = EntitiesFactory.getInstance();
	private ArrayList<String> exceptionMessanger = new ArrayList<String>();

	public DBManager() {
		export_import_entities = (IExportImportEntities) entities_factory
				.getObject(IExportImportEntities.class);
		db = ReaderFromFile.getDBFromFile();
		if (db == null) {
			db = (IDataBase) entities_factory.getObject(IDataBase.class);
		}
		masterList.addAll(db.getMasterList());
		garageList.addAll(db.getGarageList());
		orderList.addAll(db.getOrderList());
	}

	public ArrayList<String> getEmptyGarage() {
		return WorkerWithGarage.getEmptyGarage(garageList);
	}

	public ArrayList<String> getOrdersByMaster(String masterName) {
		return WorkerWithMaster.getOrdersByMaster(masterName, masterList);
	}

	public ArrayList<String> getMastersByOrder(Integer numberOrder) {
		return WorkerWithOrder.getMastersByOrder(numberOrder, orderList);
	}

	public ArrayList<String> getNumberEmptyPlaces(Date date) {
		return WorkerWithGarage.getNumberEmptyPlaces(masterList, garageList,
				date);
	}

	public ArrayList<String> getNextFreeDate() {
		return WorkerWithOrder.getNextFreeDate(orderList);
	}

	public ArrayList<String> SortOrderByBeginningDate() {
		return WorkerWithOrder.SortOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_BEGINING_DATE));
	}

	public ArrayList<String> SortOrderByDeadlineDate() {
		return WorkerWithOrder.SortOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_DEADLINE_DATE));
	}

	public ArrayList<String> SortOrderByFillingDate() {
		return WorkerWithOrder.SortOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_FILLING_DATE));
	}

	public ArrayList<String> SortOrderByPrice() {
		return WorkerWithOrder.SortOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_PRICE));
	}

	public ArrayList<String> SortMasterByEmployment() {
		return WorkerWithMaster.SortMaster(masterList,
				SortBy.SortBy(SortObjectBy.SORT_MASTER_BY_EMPLOYMENT));
	}

	public ArrayList<String> SortMasterByName() {
		return WorkerWithMaster.SortMaster(masterList,
				SortBy.SortBy(SortObjectBy.SORT_MASTER_BY_NAME));
	}

	public ArrayList<String> SortMadingOrderByBeginningDate() {
		return WorkerWithOrder.getListMadingOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_BEGINING_DATE));

	}

	public ArrayList<String> SortMadingOrderByDeadlineDate() {
		return WorkerWithOrder.getListMadingOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_DEADLINE_DATE));
	}

	public ArrayList<String> SortMadingOrderByFillinggDate() {
		return WorkerWithOrder.getListMadingOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_FILLING_DATE));

	}

	public ArrayList<String> SortMadingOrderByPrice() {
		return WorkerWithOrder.getListMadingOrder(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_PRICE));

	}

	public ArrayList<String> SortDeletedOrderByPeriodByBeginningDate(
			Date begin, Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_BEGINING_DATE),
				OrderStatus.DELETED, begin, end);
	}

	public ArrayList<String> SortCanceledOrderByPeriodByBeginningDate(
			Date begin, Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_BEGINING_DATE),
				OrderStatus.CANCELED, begin, end);
	}

	public ArrayList<String> SortMadeOrderByPeriodByBeginningDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_BEGINING_DATE),
				OrderStatus.MADE, begin, end);
	}

	public ArrayList<String> SortDeletedOrderByPeriodByDeadlineDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_DEADLINE_DATE),
				OrderStatus.DELETED, begin, end);
	}

	public ArrayList<String> SortCanceledOrderByPeriodByDeadlineDate(
			Date begin, Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_DEADLINE_DATE),
				OrderStatus.CANCELED, begin, end);
	}

	public ArrayList<String> SortMadeOrderByPeriodByDeadlineDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_DEADLINE_DATE),
				OrderStatus.MADE, begin, end);
	}

	public ArrayList<String> SortDeletedOrderByPeriodByFillingDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_FILLING_DATE),
				OrderStatus.DELETED, begin, end);
	}

	public ArrayList<String> SortCanceledOrderByPeriodByFillingDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_FILLING_DATE),
				OrderStatus.CANCELED, begin, end);
	}

	public ArrayList<String> SortMadeOrderByPeriodByFillingDate(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_FILLING_DATE),
				OrderStatus.MADE, begin, end);
	}

	public ArrayList<String> SortDeletedOrderByPeriodByPrice(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_PRICE),
				OrderStatus.DELETED, begin, end);
	}

	public ArrayList<String> SortCanceledOrderByPeriodByPrice(Date begin,
			Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_PRICE),
				OrderStatus.CANCELED, begin, end);
	}

	public ArrayList<String> SortMadeOrderByPeriodByPrice(Date begin, Date end) {
		return WorkerWithOrder.getOrderByPeriod(orderList,
				SortBy.SortBy(SortObjectBy.SORT_ORDERS_BY_PRICE),
				OrderStatus.MADE, begin, end);
	}

	public ArrayList<String> addMaster(String masterName) {
		IMaster master=(IMaster) entities_factory.getObject(IMaster.class);
		master.setNameMaster(masterName);
		return WorkerWithMaster.addMaster(masterList, master);
	}

	public ArrayList<String> deleteMaster(String masterName) {
		return WorkerWithMaster.deleteMaster(masterList, masterName);
	}

	public ArrayList<String> addGarage(Integer numberGarage) {
		exceptionMessanger.clear();
		if (auto_properties.getGarageManager() == true) {
			IGarage garage= (IGarage) entities_factory.getObject(IGarage.class);
			garage.setNumberGarage(numberGarage);
			return WorkerWithGarage.addGarage(garageList, garage);
		} else {
			exceptionMessanger.add(Messager.THIS_ACTION_NOT_ALLOWED);
			return exceptionMessanger;
		}

	}

	public ArrayList<String> deleteGarage(Integer numberGarage) {
		exceptionMessanger.clear();
		if (auto_properties.getGarageManager()) {
			return WorkerWithGarage.deleteGarage(garageList, numberGarage);
		} else {
			exceptionMessanger.add(Messager.THIS_ACTION_NOT_ALLOWED);
			return exceptionMessanger;
		}

	}

	public ArrayList<String> addOrder(Integer orderNumber, String masterName,
			Integer numberGarage) {
		IOrder order=(IOrder) entities_factory.getObject(IOrder.class);
		order.setNumberOrder(orderNumber);
		return WorkerWithOrder.addOrder(orderList, order, masterList,
				garageList, masterName, numberGarage);
	}

	public ArrayList<String> markOrderDeleted(Integer numberOrder) {
		exceptionMessanger.clear();
		if (auto_properties.getPermissionDeleteOrder() == true) {
			return WorkerWithOrder.markOrder(orderList, OrderStatus.DELETED,
					numberOrder);
		} else {
			exceptionMessanger.add(Messager.THIS_ACTION_NOT_ALLOWED);
			return exceptionMessanger;
		}

	}

	public ArrayList<String> markOrderCanceled(Integer numberOrder) {
		return WorkerWithOrder.markOrder(orderList, OrderStatus.CANCELED,
				numberOrder);
	}

	public ArrayList<String> markOrderMade(Integer numberOrder) {
		return WorkerWithOrder.markOrder(orderList, OrderStatus.MADE,
				numberOrder);
	}

	public ArrayList<String> ShirtTimeOrder(Date newDate, Integer numberOrder) {
		exceptionMessanger.clear();
		if (auto_properties.getPermissionShiftTimeOrder()) {
			return WorkerWithOrder.ShirtTimeOrder(orderList, newDate,
					numberOrder);
		} else {
			exceptionMessanger.add(Messager.THIS_ACTION_NOT_ALLOWED);
			return exceptionMessanger;
		}

	}

	public ArrayList<String> cloneOrder(Integer numberOrder) {
		exceptionMessanger.clear();
		for (IOrder o : orderList) {
			if (o.getNumberOrder() == numberOrder) {
				exceptionMessanger.addAll(WorkerWithOrder.cloneOrder(orderList,
						o, masterList, garageList));
			}
		}

		if (exceptionMessanger.isEmpty()) {
			exceptionMessanger.add(Messager.ERROR_CLONE);
		}

		return exceptionMessanger;

	}

	public ArrayList<String> exportGarages() {
		return export_import_entities.ExportGarages(garageList);

	}

	public ArrayList<String> exportMasters() {
		return export_import_entities.ExportMasters(masterList);

	}

	public ArrayList<String> exportOrders() {
		return export_import_entities.ExportOrders(orderList);
	}

	public ArrayList<String> importGarages() {
		return export_import_entities.ImportGarages(garageList);
	}

	public ArrayList<String> importMasters() {
		return export_import_entities.ImportMasters(masterList);
	}

	public ArrayList<String> importOrders() {
		return export_import_entities.ImportOrders(orderList);
	}

	public ArrayList<String> saveData() {
		exceptionMessanger.clear();
		db.saveGarageListToBD(garageList);
		db.saveMasterListToBD(masterList);
		db.saveOrderListToBD(orderList);
		WriterInFile.saveData(db);

		exceptionMessanger.add(Messager.SUCCESS_RESAVE_DATA);
		return exceptionMessanger;
	}

}
